package com.peng.ivos.application.service.impl;

import com.peng.ivos.application.mapper.ApplicationMapper;
import com.peng.ivos.application.pojo.dto.ApplicationSaveParam;
import com.peng.ivos.application.pojo.dto.ApplicationQuery;
import com.peng.ivos.application.pojo.entity.Application;
import com.peng.ivos.application.pojo.vo.ApplicationVO;
import com.peng.ivos.application.service.ApplicationService;
import com.peng.ivos.audit.mapper.AuditMapper;
import com.peng.ivos.audit.pojo.dto.AuditQuery;
import com.peng.ivos.audit.pojo.entity.Audit;
import com.peng.ivos.audit.pojo.vo.AuditVO;
import com.peng.ivos.base.enums.ApplicationStatusEnum;
import com.peng.ivos.base.enums.AuditStatusEnum;
import com.peng.ivos.base.enums.VehicleStatusEnum;
import com.peng.ivos.base.response.JsonResult;
import com.peng.ivos.base.response.StatusCode;
import com.peng.ivos.user.mapper.UserMapper;
import com.peng.ivos.user.pojo.dto.UserQuery;
import com.peng.ivos.user.pojo.vo.UserVO;
import com.peng.ivos.vehicle.mapper.VehicleMapper;
import com.peng.ivos.vehicle.pojo.dto.VehicleQuery;
import com.peng.ivos.vehicle.pojo.entity.Vehicle;
import com.peng.ivos.vehicle.pojo.vo.VehicleVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author： Peng
 * @date： 2024/5/24
 * @version: 1.0
 */
@Service
@Slf4j
@Transactional//事务注解，保证事务原子性
public class ApplicationServiceImpl implements ApplicationService {
    @Autowired
    private ApplicationMapper applicationMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AuditMapper auditMapper;
    @Autowired
    private VehicleMapper vehicleMapper;

    @Override
    public JsonResult addApplication(ApplicationSaveParam applicationSaveParam) {

        Application application = Application.builder()
                .id(applicationSaveParam.getId())
                .userId(applicationSaveParam.getUserId())
                .username(applicationSaveParam.getUsername())
                .startTime(applicationSaveParam.getStartTime())
                .endTime(applicationSaveParam.getEndTime())
                .imgUrl(applicationSaveParam.getImgUrl())
                .departureAddr(applicationSaveParam.getDepartureAddr())
                .destinationAddr(applicationSaveParam.getDestinationAddr())
                .reason(applicationSaveParam.getReason())
                .remark(applicationSaveParam.getRemark())
                .status(applicationSaveParam.getStatus())
                .vehicleId(null)
                .rejectReason(null)
                .createTime(new Date())
                .updateTime(new Date())
                .auditUserIdList(applicationSaveParam.getAuditUserIdList())
                .build();
        if (applicationSaveParam.getId() != null){
            log.debug("开始更新");
            return null;
        } else {
            application.setStatus(ApplicationStatusEnum.PENDING.getCode());
            int i1 = applicationMapper.insertApplication(application);
            ApplicationQuery query = new ApplicationQuery();
            BeanUtils.copyProperties(applicationSaveParam, query);
            List<ApplicationVO> applicationVOList = applicationMapper.selectApplicationByExample(query);
            Long applicationId = applicationVOList.get(0).getId();
            Audit audit = new Audit();
//            audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            audit.setApplicationId(applicationId);
            for (int i = 0; i < applicationSaveParam.getAuditUserIdList().size(); i++) {
                audit.setAuditUserId(applicationSaveParam.getAuditUserIdList().get(i));
                audit.setAuditSort(i);
                if(i==0){
                    //i==0表示第一个审批单,这个审批单需要设置为"待我审核"(当前审批人是申请人的上级)
                    audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
                }else{
                    //其他审批单状态 为"待他人审核"(当前审批人是申请人的上上级)
                    audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
                }
                auditMapper.insertAudit(audit);
            }
                return JsonResult.success("新增申请单和审批单成功");

        }
    }

    @Override
    public JsonResult getApplicationList(ApplicationQuery applicationQuery) {
        if (applicationQuery == null){
            return JsonResult.error(StatusCode.DATA_UNEXISTS,"用车列表查询参数不能为空");
        }
        //从application库中获取除申请人以外的其他数据
        List<ApplicationVO> applicationVOList = applicationMapper.selectApplicationByExample(applicationQuery);
        //从audit库中获取审批人id和username
        AuditQuery auditQuery = new AuditQuery();
        UserQuery userQuery = new UserQuery();
        ArrayList<Long>  auditUserIdList = new ArrayList<>();
        ArrayList<String> auditUsernameList = new ArrayList<>();
        //遍历applicationVOList
        for (int i = 0; i < applicationVOList.size(); i++) {
            ApplicationVO applicationVO = applicationVOList.get(i);
            Long applicationId = applicationVO.getId();
            //设置查询参数
            auditQuery.setApplicationId(applicationId);
            log.debug("审批单查询参数，auditQuery:{}",auditQuery);
            //查询审批单
            for (AuditVO auditVO : auditMapper.selectAuditByExample(auditQuery)) {
                Long auditUserId = auditVO.getAuditUserId();
                auditUserIdList.add(auditUserId);
                userQuery.setId(auditUserId);
                List<UserVO> userVOList = userMapper.selectUserByExample(userQuery);
                String auditUsername = userVOList.get(0).getUsername();
                auditUsernameList.add(auditUsername);
            }
            //将审批人昵称集合和审批人ID集合拼接
            String auditUsernameArray = auditUsernameList.stream().collect(Collectors.joining(","));
            log.debug("审批人昵称集合，auditUsernameArray:{}",auditUsernameArray);
            log.debug("审批人ID集合，auditUserIdList:{}",auditUserIdList);
            //将审批人ID和审批人昵称列表赋值给applicationVO
            applicationVO.setAuditUserIdList(auditUserIdList);
            applicationVO.setAuditUsernameList(auditUsernameArray);
            //清空审批人信息列表中的原数据
            auditUserIdList.clear();
            auditUsernameList.clear();
        }
        return JsonResult.success(applicationVOList);
    }

    @Override
    public JsonResult cancelApplication(Long applicationId) {
        if (applicationId == null){
            return JsonResult.error(StatusCode.DATA_UNEXISTS,"撤销申请ID不能为空");
        }
        Application application = Application.builder()
                .id(applicationId)
                .status(ApplicationStatusEnum.CANCEL.getCode())
                .build();
        int i1 = applicationMapper.update(application);
        int i2 = auditMapper.deleteByApplicationId(applicationId);
        if (i1 >0 && i2 >0){
            return JsonResult.success("撤销申请成功");
        } else {
            return JsonResult.error("撤销申请失败");
        }

    }

    @Override
    public JsonResult distributeVehicle(Long applicationId, Long vehicleId) {
        if (applicationId == null || vehicleId == null){
            return JsonResult.error(StatusCode.DATA_UNEXISTS,"申请单ID或车辆ID不能为空");
        }
        //修改申请表分配车辆id和状态
        ApplicationVO applicationVO = applicationMapper.selectApplicationById(applicationId);
        Application application = new Application();
        BeanUtils.copyProperties(applicationVO,application);
        application.setVehicleId(vehicleId);
        application.setStatus(ApplicationStatusEnum.ALLOCATION.getCode());
        application.setUpdateTime(new Date());
        int i1 = applicationMapper.update(application);

        //修改车辆状态为未占用
        VehicleQuery vehicleQuery = new VehicleQuery();
        vehicleQuery.setId(vehicleId);
        VehicleVO vehicleVO = vehicleMapper.selectByExample(vehicleQuery).get(0);
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(vehicleVO,vehicle);
        vehicle.setStatus(VehicleStatusEnum.OCCUPIED.getCode());
        Integer i2 = vehicleMapper.updateVehicle(vehicle);
        if (i1 >0 && i2 >0){
            return JsonResult.success("分配车辆成功");
        } else {
            return JsonResult.error("分配车辆失败");
        }
    }

    @Override
    public JsonResult backVehicle(Long applicationId, Long vehicleId) {
        if (applicationId == null || vehicleId == null){
            return JsonResult.error(StatusCode.DATA_UNEXISTS,"申请单ID或车辆ID不能为空");
        }
        //修改申请表分配车辆id和状态
        ApplicationVO applicationVO = applicationMapper.selectApplicationById(applicationId);
        Application application = new Application();
        BeanUtils.copyProperties(applicationVO,application);
        application.setVehicleId(vehicleId);
        application.setStatus(ApplicationStatusEnum.END.getCode());
        application.setUpdateTime(new Date());
        int i1 = applicationMapper.update(application);

        //修改车辆状态为未占用
        VehicleQuery vehicleQuery = new VehicleQuery();
        vehicleQuery.setId(vehicleId);
        VehicleVO vehicleVO = vehicleMapper.selectByExample(vehicleQuery).get(0);
        Vehicle vehicle = new Vehicle();
        BeanUtils.copyProperties(vehicleVO,vehicle);
        vehicle.setStatus(VehicleStatusEnum.UNOCCUPIED.getCode());
        Integer i2 = vehicleMapper.updateVehicle(vehicle);
        if (i1 >0 && i2 >0){
            return JsonResult.success("归还车辆成功");
        } else {
            return JsonResult.error("归还车辆失败");
        }
    }

}
